package ipc;

import graph.gviz.DotViewer.DotViewerFrame;


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.io.IOException;


import rddl.State;

class dot2dd{
	
		public myDD _theDD;
	
		public dot2dd(String infile) throws Exception{
			_theDD = new myDD();
		
		boolean done = false;
	
			do{ 	
				FileInputStream fis = new FileInputStream(infile);
				InputStream is = new BufferedInputStream(fis);
				StringBuilder sb = new StringBuilder();
				int c = 0;

				while( true ){
					try {
						c = is.read();
					} catch (IOException e) {
						e.printStackTrace();
						System.exit(1);
					}
					if(c == -1 || c == '\n'){

						if(sb.length() != 0){
							try{
								process(sb.toString());
							}catch(Exception e){
								break;
							}				
						 }
						sb = null;
						if( c == -1 ){
							done = true;
							break;
						}
						sb = new StringBuilder();
					}
					else{
						sb.append((char)c);
					}
				}
				is.close();
				fis.close();
			}while( !done );
		}
	
		void process(String str){
		//	System.out.println("Processing " + str);
			if(isNode(str)){
		//		System.out.println("Node");
				String label = getLabel(str);
//				System.err.print(label+"->");
				label = reconstructFluent(label);
//				System.out.println(label);
//				try{
//					System.in.read();
//				}catch(Exception e){
//				}

				int id = getName(str).hashCode();
				_theDD.addNode(id,label);
			}
			
			else if(isEdge(str)){
		//		System.out.println("Edge");
				String head = getHead(str);
				String tail = getTail(str); 
				boolean edge = getEdge(str);
		//		System.out.println("Edge: " + edge);
				int headid = head.hashCode();
				int tailid = tail.hashCode();
				_theDD.addEdge(tailid, headid, edge);
			}
		//	try{
		//		System.in.read();
		//	}catch(Exception e){
		//	}

		}
	
		private String reconstructFluent(String s) {
			if( s.equals("noop") ) s="[]";
			if( s.equals("noop") || s.equals("[]") || s.indexOf('_')== -1)return s;
			s = s.trim();
			s = s.replace("___", ";");
			boolean comma = false;

			StringBuilder sb = new StringBuilder();
			for( int i = 0 ; i < s.length(); ++i ){
				if( s.charAt(i) == '_' && s.charAt(i+1) != '_' ){
					if( comma ) sb.append(", ");
					else sb.append('-');
				}

				else if( s.charAt(i) == '_' && s.charAt(i+1) == '_' ){
					comma = true;
					++i;
					sb.append('[');
				} 	
				else if( s.charAt(i) == ';' ){
					comma = false;
					sb.append("];");
				}
				else
					sb.append(s.charAt(i));

				

				
			}
			sb.append("]");

//			System.out.println("reconstructed " + sb.toString());

			return sb.toString();
			
		}

		public boolean isNode(String str){
			return str.indexOf("node") != -1;
		}

		public String getLabel(String str){
//			System.err.println(str);
			int opB = str.lastIndexOf('[');
//			System.out.println("opB " + opB);
			int opQ = str.indexOf("\"", opB);
//			System.out.println("opQ " + opQ);
			int clQ = str.indexOf('\"', opQ+1);
//			System.out.println("clQ " + clQ);
			String ret = str.substring(opQ+1, clQ).trim();
		//	System.out.println("Label " + ret);
			return ret;
		}

		public String getName(String str){
			int opQ = str.indexOf('\"');
			int clQ = str.indexOf('\"', opQ+1);
			String ret = str.substring(opQ+1, clQ).trim();
		//	System.out.println("Name "+ ret);
			return ret;
		}	

		public boolean isEdge(String str){
			return str.indexOf("->") != -1;
		}

		public String getTail(String str){
			return getName(str);
		}

		public String getHead(String str){
			int opH = str.indexOf("->");
			int opQ = str.indexOf('\"', opH);
			int clQ = str.indexOf('\"', opQ+1);
			String ret = str.substring(opQ+1, clQ).trim();
		//	System.out.println("Head " + ret);
			return ret;
		}
		
		public boolean getEdge(String str){
			String lab = getLabel(str);
			return lab.equalsIgnoreCase("true");
		}

		public String toString(){
			return _theDD.toString();
		}
		
		public myDD getDD(){
			return _theDD;
		}
	
		public static void main(String[] args) throws Exception{
			myDD _dd = new dot2dd(args[0]).getDD();
			System.err.println(_dd._ID2var.toString());

			System.err.println(_dd._ID2low.toString());

			System.err.println(_dd._ID2high.toString());
		}
}
